#ifndef _FIFO_H_
#define _FIFO_H_

#include "crossplat_def.h"
#include <stdint.h>
//#define SPT_READ_FRAME	1
class CFIFO_buf
{
public:
	CFIFO_buf();
	~CFIFO_buf();

protected:
	bool m_bOpened;			//�Ƿ��Ѿ����򿪹�
	bool m_bOverWrite;
	uint32_t m_pidx;		//����������product index
	uint32_t m_cidx;	    //���ĵ�����consume index

	uint32_t m_buf_size;	//�����С����
	unsigned char*    m_buf;//����
	CCross_Lock m_lock;
	uint32_t m_file_offset;	//���ļ����л�����ƫ��
	bool   m_showlog;
public:

	int open(uint32_t size);
	int read(unsigned char * buf, uint32_t size,  bool bPeek = false);


	int write(unsigned char * buf, uint32_t data_size,bool bLock = true);
	int read_pos(uint32_t offset,unsigned char * buf, uint32_t size,bool bConsume);

	int close();
	void reset(uint32_t file_offset = 0);
	//��ǿ���ܣ���ʡ�ڴ�ռ�ͬʱ��Ҳ��߶�дЧ��
	//��ȡ�ڴ��ַ��ֱ�ӽ��ڴ��ַ���ظ��ϲ�ʹ�ã���ȥ���ڴ濽����ʱ��
	uchar_t* GetBufOffset(uint32_t size, uint32_t * leaf_size,uchar_t ** tail_buf);
	uchar_t* GetFreeBuf(uchar_t ** tail_buf, uint32_t * leaf_size);

	//����һ��������
	int ConsumeBuf(uint32_t size,bool bLock = true);
	//������һ��������
	int ProductBuf(uint32_t size,bool bLock = true);
	uint32_t GetDataSize();
	uint32_t GetFreeSize();
	void Lock ()
	{
		m_lock.Lock();
	}
	void Unlock()
	{
		m_lock.UnLock();
	}
	bool IsOpen()
	{
		return m_bOpened;
	}
	void showlog(bool bEnable)
	{
		m_showlog = bEnable;
	}
protected:
	int read_buf(uint32_t offset,unsigned char * buf,uint32_t size,bool bConsume);
public:
	void SetFileOffsset(uint32_t offset)
	{
		m_file_offset = offset;
	}
	uint32_t GetFIFOSize()
	{
		return m_buf_size;
	}

	bool IsEmpty()
	{
		return (m_pidx == m_cidx);
	}

	uint32_t GetCurWarter()	//��ȡ��ǰ����λ
	{
        if( 0 == m_buf_size)
        {
            return 0;
        }
		return  (GetDataSize() * 100) / m_buf_size;
	}

	uint32_t GetCurProduct()
	{
		return m_pidx;
	}

	uint32_t GetCurConsume()
	{
		return m_cidx;
	}

#ifdef SPT_READ_FRAME
	int GetNextFrameSize()
	{
		return m_nextFrameSize;
	}
#endif
};

typedef enum
{
	FIFO_ERR_SIZE      = -3005,
	FIFO_ERR_NOTENOUGH = -3004,
	FIFO_ERR_NODATA    = -3002,
	FIFO_ERR_OPENED    = -3001,
	FIFO_ERR_NOOPEN	   = -3000,
	FIFO_ERR_PARAM     = -2009,
	FIFO_ERR_TIMEOUT   = -2008,
	FIFO_ERR_OVERDATA  = -2007,
	FIFO_NO_EER = 0,
}ERR_FIFO_E;

#endif /* _FIFO_H_ */
